<template>
  <el-form-item v-bind="formItemAttr" :prop="schema.prop">
    <el-select
      clearable
      v-bind="{ ...selectAttr, ...$attrs }"
      :loading="loading"
      @change="valueChange"
      style="width: 100%"
    >
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      />
    </el-select>
  </el-form-item>
</template>

<script setup>
import { ref, getCurrentInstance } from 'vue'
import { lowCodeAttr } from '../../common/util'
import { handleApi } from '../../common/api'
defineOptions({ name: 'SelectCom' })

let timer = null

const instance = getCurrentInstance()

const props = defineProps({
  schema: {
    type: Object,
    required: true
  }
})
const loading = ref()
const schema = props.schema
const event = schema.event || {}
const options = ref(schema.options || [])
const api = schema.api
const fieldNames = schema.fieldNames || { label: 'label', value: 'value' }
const searchName = schema.searchName || 'name'
const formItemAttr = {}

const selectAttr = {}

const formItemIncludeAttrs = ['label', 'prop', 'labelWidth']
const selectExcludeAttrs = ['fieldNames', 'searchName']

for (const key in schema) {
  if (!lowCodeAttr.includes(key)) {
    const value = schema[key]
    if (formItemIncludeAttrs.includes(key)) {
      formItemAttr[key] = value
    } else {
      if (!selectExcludeAttrs.includes(key)) {
        selectAttr[key] = value
      }
    }
  }
}

if (selectAttr.remote) {
  selectAttr['remote-method'] = remoteMethod
}

function remoteMethod(query) {
  if (timer) {
    clearTimeout(timer)
    timer = null
  }
  timer = setTimeout(() => {
    getOptionsByApi(query)
  }, 600)
  return true
}

function valueChange(e) {
  const value = {
    schema,
    options: options.value,
    value: e
  }
  if (schema?.event?.change) {
    schema.event.change(value)
  }
}

function getOptionsByApi(query) {
  if (!api) {
    return
  }
  loading.value = true
  const extra = {}
  if (selectAttr.remote) {
    extra[searchName] = query
  }
  handleApi(api, instance, extra)
    .then((rows) => {
      options.value = rows.map((item) => ({
        label: item[fieldNames.label],
        value: item[fieldNames.value]
      }))
      if (event && event.loaded) {
        event.loaded(rows)
      }
    })
    .finally(() => {
      loading.value = false
    })
}

getOptionsByApi()
</script>
